﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;

namespace HYCodeBase.ObjectPersistentSuit
{
	[Serializable]
	public sealed class NoneSerizeElementPacker<X> : ISerializable where X : class
	{
		public X ThisValue
		{
			get
			{
				return this.m_thisValue;
			}
			private set
			{
				this.m_thisValue = value;
			}
		}

		public NoneSerizeElementPacker(X input)
		{
			this.ThisValue = input;
		}

		public NoneSerizeElementPacker(SerializationInfo info, StreamingContext context)
		{
			try
			{
				this.ThisValue = default(X);
				MethodInfo methodInfo = null;
				if (NoneSerizeElementPacker<X>.m_useTransformer == null)
				{
					methodInfo = this.FindPareMethod();
				}
				string @string = info.GetString("this");
				if (null != methodInfo)
				{
					this.ThisValue = (X)((object)methodInfo.Invoke(null, null));
				}
				else
				{
					IClassInformationTransformer<X> classInformationTransformer = this.CreatOneTransformer();
					if (classInformationTransformer != null)
					{
						this.ThisValue = classInformationTransformer.TransformStringToClass(@string);
					}
				}
			}
			catch (Exception)
			{
				this.ThisValue = default(X);
			}
		}

		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
		{
			MethodInfo right = null;
			if (NoneSerizeElementPacker<X>.m_useTransformer == null)
			{
				right = this.FindPareMethod();
			}
			string value = string.Empty;
			if (null != right)
			{
				value = this.ThisValue.ToString();
			}
			else
			{
				IClassInformationTransformer<X> classInformationTransformer = this.CreatOneTransformer();
				if (classInformationTransformer != null)
				{
					value = classInformationTransformer.TransformClassToString(this.ThisValue);
				}
			}
			info.AddValue("this", value);
		}

		private IClassInformationTransformer<X> CreatOneTransformer()
		{
			IClassInformationTransformer<X> classInformationTransformer = null;
			if (NoneSerizeElementPacker<X>.m_useTransformer != null)
			{
				return NoneSerizeElementPacker<X>.m_useTransformer;
			}
			if (null == NoneSerizeElementPacker<X>.m_useType)
			{
				NoneSerizeElementPacker<X>.m_useType = this.FindOneUseType();
			}
			if (null != NoneSerizeElementPacker<X>.m_useType)
			{
				try
				{
					classInformationTransformer = (IClassInformationTransformer<X>)Activator.CreateInstance(NoneSerizeElementPacker<X>.m_useType);
				}
				catch (Exception)
				{
					classInformationTransformer = null;
				}
			}
			NoneSerizeElementPacker<X>.m_useTransformer = classInformationTransformer;
			return classInformationTransformer;
		}

		private Type FindOneUseType()
		{
			Type result = null;
			List<Type> list = TypeFinder.GetTypeFinder(false).FindTypesInheritFromInput(typeof(IClassInformationTransformer<X>));
			if (list != null && list.Count != 0)
			{
				result = list[0];
			}
			return result;
		}

		private MethodInfo FindPareMethod()
		{
			MethodInfo result = null;
			try
			{
				result = typeof(X).GetMethod("Parse", new Type[]
				{
					typeof(string)
				});
			}
			catch (Exception)
			{
				result = null;
			}
			return result;
		}

		[NonSerialized]
		private X m_thisValue;

		private const string m_keyMethodName = "Parse";

		private const string m_keyStrOfClass = "this";

		internal static Type m_useType;

		internal static IClassInformationTransformer<X> m_useTransformer;
	}
}
